Skip to content

Synacktiv-contrib/exploiting-cve-2017-5123

Repository files navigation

Exploiting CVE-2017-5123

Introduction

This repository is an addition to the article published in MISC Magazine #96.

We achieved to elevate our privileges in a reliable way, on our virtual machine with SMEP / SMAP and KASLR enabled. It should however be noted that the system if left in an unstable state and that a oops is very likely to occur.

Contents of this repository

In the folder configs/, you will find configuration files for the Linux kernel and Busybox, each one being sightly different of the default ones.

The folder binaries/ contains all the pre-built binaries that you will need to reproduce our test environment, such as a whole rootfs ready to be used with QEMU.

linux-stable is a git submodule pointing to a vulnerable revision of the Linux kernel. Use git submodule update --recursive to fetch it (if you a least 1GB free on your system...). Same thing goes for busybox.

Environment setup

Our environment is based on a QEMU x86 virtual machine with a folder shared with the host via 9P. A vulnerable version of the kernel (ff33952e4d23) is compiled along with a statically-linked build of Busybox.

Kernel configuration

Our configuration is pretty simple, since we do not need to support any kind of exotic architecture or hardware. Is has been generated by running make defconfig and some features were enabled, to support QEMU's networking and folder sharing:

CONFIG_BLK_MQ_VIRTIO=y
CONFIG_MEMORY_BALLOON=y
CONFIG_BALLOON_COMPACTION=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_NET_9P_DEBUG=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_BLK_SCSI=y
CONFIG_VIRTIO_NET=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_9P_FS=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y

GDB scripts and debugging symbols were also added to ease the developpement of the first PoCs:

CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y

Please note that in this version, KASLR is enabled by default on x86. Since the kernel mapped at a different addresses after each reboot, GDB will not be able to match the symbol file with it. You have then two options: performing tests without KASLR or passing the base address of the kernel to symbol-file when loading the symbols in GDB.

After compiling it, you will find the bzImage in linux-stable/arch/x86/boot/bzImage.

This file is present in binaries/bzImage and our configuration file in confifs/kernel.config. To use it, you only have to copy it as .config in linux-stable.

Compiling Busybox

We used the last stable version of Busybox, 1.28. The only setting to change is CONFIG_STATIC, set it to y. Compiling it should not cause any issue.

Our configuration file is available into configs/busybox.config and a statically-compiled binary in binaries/busybox. As for Linux, just copy it as .config in Busybox's sources folder.

Assembling it together

Busybox already implements an init process that will try to execute /etc/init.d/rcS. Usually, it is provided by your distribution (potentially with a different name) but we will have to do it by ourselves here! This script will create and mount several mandatory system folders (proc, sys, dev), our folder shared with the host and drop us into an unprivilegied shell:

for i in $(seq 1 9); do mknod /dev/tty$i c 4 1; done

mknod -m 0666 /dev/null c 1 3
mknod -m 0660 /dev/ttyS0 c 4 64

mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev

mkdir -p /mnt/share
mount -t 9p -o trans=virtio share /mnt/share/ -oversion=9p2000.L,posixacl,sync
chmod 777 /mnt/share/

export ENV=/etc/profile
setsid cttyhack setuidgid 1000 sh

umount /proc
umount /sys
umount /dev

poweroff -f

The file /etc/profile is not mandatory but kind of useful during our tests, more especially when the exploit was not reliable and it took several tries to obtain root privileges.

Exploit

The process behing exploit's writing is fairly documented in MISC 96: we use unsafe_put_user to probe memory until we find the base address of the heap. Then, thousands of calls to clone let us spray numerous cred structures in memory. During our tests, their position in memory was much more "constant" than when using fork, since it allocates less structures for the new task.

What's left

Exiting the child will cause a kernel oops, due to a faulty paging request, this needs to be correctly handled.

Contributing

If you want to improve the reliability of this exploit or add documentation, contributions are welcome! We may also have also made mistakes or imprecisions on some concepts, do not hesitate to open an issue if you think something is wrong.

Useful links

Linux kernel

Exploitation

About

Source code and configuration files related to our article in MISC96

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published